# Title     : TODO
# Objective : TODO
# Created by: Administrator
# Created on: 2019/7/24

library(ggrepel)
library(optparse)
library(stringr)
library(magrittr)
library(tidyverse)
library(rstatix)
library(car)

createWhenNoExist <- function(f) {
  !dir.exists(f) && dir.create(f)
}

option_list <- list(
  make_option("--i", default = "AllMet_Raw.txt", type = "character", help = "metabolite data file"),
  make_option("--g", default = "group.txt", type = "character", help = "sample group file"),
  make_option("--config", default = "config.json", type = "character", help = "config file")
)
opt <- parse_args(OptionParser(option_list = option_list))

args <- commandArgs(trailingOnly = F)
scriptPath <- dirname(sub("--file=", "", args[grep("--file", args)]))
source(str_c(scriptPath, "/base.R"))

configJson <- fromJSON(opt$config)
configJson
isPaired <- configJson$isPaired %>%
  as.logical()
diffMethod <- configJson$method
fcMethod <- configJson$fcMethod
pValue <- configJson$pValue %>%
  as.numeric()
tmpFdr <- configJson$fdr %>%
  as.numeric()
log2FC <- configJson$log2FC %>%
  as.numeric()

options(digits = 3)

isT <- function(data1, data2) {
  var1 <- var(data1)
  if (var1 == 0) {
    return(F)
  }
  d1Test <- shapiro.test(data1)
  d1P <- d1Test$p.value
  if (d1P < 0.05) {
    return(F)
  }
  var2 <- var(data2)
  if (var2 == 0) {
    return(F)
  }
  d2Test <- shapiro.test(data2)
  d2P <- d2Test$p.value
  if (d2P < 0.05) {
    return(F)
  }
  data <- tibble(value = c(data1, data2), group = factor(c(rep(1, length(data1)), rep(2, length(data2)))))
  bTest <- leveneTest(value ~ group, data)
  bp <- bTest$`Pr(>F)`[1]
  if (bp < 0.05) {
    return(F)
  }
  return(T)
}

my.test <- function(data1, data2, paired, method) {
  p <- 0
  curMethod <- method
  if (curMethod == "auto") {
    b <- isT(data1, data2)
    if (b) {
      curMethod <- "t"
    }else {
      curMethod <- "u"
    }
  }

  if (curMethod == "u") {
    test <- wilcox.test(data1, data2, paired = paired)
    p <- test$p.value
    curMethod <- "wilcox.test"
  }else if (curMethod == "t") {
    tryCatch({
      test <- t.test(data1, data2, paired = paired, var.equal = T)
      p <- test$p.value
    }, error = function(e) {
      p <- 1
    })

    curMethod <- "t.test"
  }
  if (is.na(p)) {
    p <- 1
  }
  list(p = p, method = curMethod)
}

sampleInfo <- read_tsv(opt$g) %>%
  rename(SampleID = Sample) %>%
  mutate(ClassNote = as.character(ClassNote))

sampleIds <- sampleInfo$SampleID

classNotes <- unique(sampleInfo$ClassNote)
cn <- combn(classNotes, 2)

groups <- unique(sampleInfo$ClassNote)

data <- read_tsv(opt$i) %>%
  rename(Metabolite = 1) %>%
  mutate(Metabolite = factor(Metabolite, levels = unique(Metabolite))) %>%
  gather("SampleID", "Value", -Metabolite) %>%
  inner_join(sampleInfo, by = c("SampleID")) %>%
  filter(ClassNote %in% groups)

groupTb <- data %>%
  group_by(Metabolite)

diffMethod<-"u"

if (diffMethod == "u") {
  testTb <- groupTb %>%
    wilcox_test(formula = Value ~ ClassNote)
}else if (diffMethod == "t") {
  testTb <- groupTb %>%
    t_test(formula = Value ~ ClassNote)
}else if (diffMethod == "auto") {
  testTb <- groupTb %>%
    do({
      result <- as_tibble(.)
      group1Data <- result %>%
        filter(ClassNote == groups[1]) %>%
        .$Value %>%
        unlist()
      group2Data <- result %>%
        filter(ClassNote == groups[2]) %>%
        .$Value %>%
        unlist()
      b <- isT(group1Data, group2Data)
      if (b) {
        curMethod <- "t"
      }else {
        curMethod <- "u"
      }
      if (curMethod == "u") {
        wilcox_test(formula = Value ~ ClassNote, data = result)
      }else {
        t_test(formula = Value ~ ClassNote, data = result)
      }
    }) %>%
    ungroup()
  print(testTb)
}


testTb <- testTb %>%
  add_significance(p.col = 'p', cutpoints = c(0, 0.0001, 0.01, 0.05, 1), symbols = c('***', '**', '*', 'ns')) %>%
  add_xy_position(x = 'Metabolite') %>%
  filter(p.signif != "ns") %>%
  mutate(label = str_c(p, " ", p.signif))

write_csv(testTb, "comparisons.csv")














